package com.wang.springbootinit.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.springbootinit.common.ErrorCode;
import com.wang.springbootinit.exception.BusinessException;
import com.wang.springbootinit.mapper.StudentMapper;
import com.wang.springbootinit.model.entity.Student;
import com.wang.springbootinit.model.entity.User;
import com.wang.springbootinit.model.param.StudentAddParam;
import com.wang.springbootinit.model.vo.UserStudentInfoVO;
import com.wang.springbootinit.service.StudentService;
import com.wang.springbootinit.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

/**
 * 学生服务实现类
 * 提供学生信息的增删改查等基础功能
 */
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private UserService userService;



    /**
     * 添加学生信息
     * 
     * @param param 待添加的学生信息
     * @return 新增学生的ID
     * @throws BusinessException 当学号已存在时抛出异常
     */
    @Override
    public long addStudent(StudentAddParam param) {
        // 校验性别
        if (param.getGender() != null && !isValidGender(param.getGender())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "性别参数无效");
        }
        
        // 设置创建和更新时间
        Date now = new Date();
        param.setCreateTime(now);
        param.setUpdateTime(now);
        
        // 检查学号是否已存在
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("studentNumber", param.getStudentNumber());
        if (studentMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "学号已存在");
        }

        User user = userService.getById(param.getUserId());
        if(ObjectUtil.isNull(user)){
            throw new BusinessException(ErrorCode.ACCOUNT_DOES_NOT_EXIST);
        }

        Student student = new Student();
        BeanUtils.copyProperties(param,student);
        student.setUserId(user.getId());
        studentMapper.insert(student);

        Student studentByNumber = getStudentByNumber(student.getStudentNumber());

        user.setStudentId(studentByNumber.getId());
        user.setUserName(studentByNumber.getName());
        return param.getId();
    }

    /**
     * 根据ID获取学生信息
     *
     * @param id 学生ID
     * @return 学生信息，如果不存在则返回null
     */
    @Override
    public Student getStudentById(long id) {
        return studentMapper.selectById(id);
    }

    @Override
    public Student getStudentByNumber(String number) {
        LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Student::getStudentNumber,number);
        return this.getOne(queryWrapper);
    }

    /**
     * 更新学生信息
     *
     * @param student 待更新的学生信息
     * @return 是否更新成功
     * @throws BusinessException 当学号被其他学生使用时抛出异常
     */
    @Override
    public boolean updateStudent(Student student) {
        // 校验性别
        if (student.getGender() != null && !isValidGender(student.getGender())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "性别参数无效");
        }
        
        // 检查学号是否被其他学生使用
        String studentNumber = student.getStudentNumber();
        if(StringUtils.isEmpty(studentNumber)){
            throw new BusinessException(ErrorCode.STUDENT_CODE_NOT_EXIST);
        }
        Student oldStudent = this.getStudentByNumber(studentNumber);
        if (ObjectUtil.isNull(oldStudent)) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "学生信息不存在");
        }
        if(StrUtil.isNotEmpty(student.getName())){
            oldStudent.setName(student.getName());
        }
        if(StrUtil.isNotEmpty(student.getMajor())){
            oldStudent.setMajor(student.getMajor());
        }
        if(ObjectUtil.isNotNull(student.getGender())){
            oldStudent.setGender(student.getGender());
        }
        if(StrUtil.isNotEmpty(student.getClassName())){
            oldStudent.setClassName(student.getClassName());
        }

        oldStudent.setUpdateTime(new Date());
        return studentMapper.updateById(oldStudent) > 0;
    }

    /**
     * 删除学生信息
     *
     * @param id 待删除的学生ID
     * @return 是否删除成功
     */
    @Override
    public boolean deleteStudent(long id) {
        return studentMapper.deleteById(id) > 0;
    }

    /**
     * 获取登录学生信息
     * 根据当前登录用户获取对应的学生信息
     *
     * @param request HTTP请求对象，用于获取当前登录用户
     * @return 学生信息
     * @throws BusinessException 当用户未登录时抛出异常
     */
    @Override
    public Student getLoginStudentInfo(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        
        return this.getStudentById(loginUser.getId());
    }

    /**
     * 更新学生个人信息
     * 仅允许学生更新自己的信息，且不允许修改学号
     *
     * @param student 待更新的学生信息
     * @param request HTTP请求对象，用于验证身份
     * @return 是否更新成功
     * @throws BusinessException 当用户未登录或尝试修改他人信息时抛出异常
     */
    @Override
    public boolean updateStudentInfo(Student student, HttpServletRequest request) {
        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        
        // 只允许修改自己的信息
        if (!loginUser.getId().equals(student.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        
        // 不允许修改学号
        Student oldStudent = this.getStudentById(student.getId());
        student.setStudentNumber(oldStudent.getStudentNumber());
        
        return this.updateStudent(student);
    }

    /**
     * 获取学生成绩信息
     * 获取当前登录学生的竞赛成绩和活动成绩，并计算总评分
     *
     * @param request HTTP请求对象，用于获取当前登录用户
     * @return 成绩信息，包含：
     *         - competitionScores: 竞赛成绩列表
     *         - activityScores: 活动成绩列表
     *         - averageScore: 总平均分
     * @throws BusinessException 当用户未登录时抛出异常
     */
    @Override
    public Map<String, Object> getStudentScores(HttpServletRequest request) {
        return null;
//        // 获取当前登录用户
//        User loginUser = userService.getLoginUser(request);
//        if (loginUser == null) {
//            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
//        }
//
//        Map<String, Object> result = new HashMap<>();
//
//        // 获取竞赛成绩
//        List<Score> competitionScores = scoreService.getStudentScores(loginUser.getId(), 1);
//        result.put("competitionScores", competitionScores);
//
//        // 获取活动成绩
//        List<Score> activityScores = scoreService.getStudentScores(loginUser.getId(), 2);
//        result.put("activityScores", activityScores);
//
//        // 计算总评分
//        double avgScore = Stream.concat(competitionScores.stream(), activityScores.stream())
//                .mapToDouble(Score::getScore)
//                .average()
//                .orElse(0.0);
//        result.put("averageScore", avgScore);
//
//        return result;
    }

    /**
     * 导出学生信息
     * 将所有学生信息���出为Excel文件
     *
     * @param response HTTP响应对象，用于输出文件流
     * @throws BusinessException 当导出过程出现异常时抛出
     */
    @Override
    public void exportStudents(HttpServletResponse response) {
        try {
            // 创建工作簿
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("学生信息");
            
            // 创建表头
            Row headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("学号");
            headerRow.createCell(1).setCellValue("姓名");
            headerRow.createCell(2).setCellValue("性别");
            headerRow.createCell(3).setCellValue("班级");
            headerRow.createCell(4).setCellValue("专业");
            
            // 填充数据
            List<Student> studentList = studentMapper.selectList(null);
            for (int i = 0; i < studentList.size(); i++) {
                Student student = studentList.get(i);
                Row row = sheet.createRow(i + 1);
                row.createCell(0).setCellValue(student.getStudentNumber());
                row.createCell(1).setCellValue(student.getName());
                row.createCell(2).setCellValue(student.getGender() != null ? 
                    (student.getGender() == 1 ? "男" : "女") : "");
                row.createCell(3).setCellValue(student.getClassName());
                row.createCell(4).setCellValue(student.getMajor());
            }
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=students.xlsx");
            
            // 输出文件
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "导出失败");
        }
    }

    /**
     * 导入学生信息
     * 从Excel文件批量导入学生信息
     *
     * @param file 上传的Excel文件
     * @return 是否导入成功
     * @throws BusinessException 当文件格式错误或导入过程出现异常时抛出
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importStudents(MultipartFile file) {
        try {
            // 读取Excel文件
            XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());
            XSSFSheet sheet = workbook.getSheetAt(0);
            
            // 从第二行开始读取数据（第一行是表头）
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                Student student = new Student();
                student.setStudentNumber(row.getCell(0).getStringCellValue());
                student.setName(row.getCell(1).getStringCellValue());
                student.setClassName(row.getCell(2).getStringCellValue());
                student.setMajor(row.getCell(3).getStringCellValue());
                
                // 设置时间
                Date now = new Date();
                student.setCreateTime(now);
                student.setUpdateTime(now);
                
                // 保存学生信息
                this.save(student);
            }
            return true;
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "导入失败");
        }
    }

    /**
     * 分析学生成绩
     * 分析当前登录学生的成绩情况，包括各类型成绩的统计信息
     *
     * @param request HTTP请求对象，用于获取当前登录用户
     * @return 成绩分析结果，包含各类型成绩的：
     *         - averageScore: 平均分
     *         - maxScore: 最高分
     *         - minScore: 最低分
     *         - totalCount: 成绩总数
     * @throws BusinessException 当用户未登录时抛出异常
     */
    @Override
    public Map<String, Object> analyzeStudentScores(HttpServletRequest request) {
        return null;
//        User loginUser = userService.getLoginUser(request);
//        if (loginUser == null) {
//            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
//        }
//
//        Map<String, Object> analysis = new HashMap<>();
//
//        // 获取所有成绩
//        List<Score> scores = scoreService.getStudentScores(loginUser.getId(), null);
//
//        // 按类型分组统计
//        Map<String, List<Score>> scoresByType = scores.stream()
//                .collect(Collectors.groupingBy(Score::getScoreType));
//
//        // 计算各类型的统计信息
//        scoresByType.forEach((type, typeScores) -> {
//            Map<String, Object> typeAnalysis = new HashMap<>();
//
//            // 计算平均分
//            double avgScore = typeScores.stream()
//                    .mapToDouble(Score::getScore)
//                    .average()
//                    .orElse(0.0);
//
//            // 计算最高分
//            double maxScore = typeScores.stream()
//                    .mapToDouble(Score::getScore)
//                    .max()
//                    .orElse(0.0);
//
//            // 计算最低分
//            double minScore = typeScores.stream()
//                    .mapToDouble(Score::getScore)
//                    .min()
//                    .orElse(0.0);
//
//            typeAnalysis.put("averageScore", avgScore);
//            typeAnalysis.put("maxScore", maxScore);
//            typeAnalysis.put("minScore", minScore);
//            typeAnalysis.put("totalCount", typeScores.size());
//
//            analysis.put("type" + type, typeAnalysis);
//        });
//
//        return analysis;
    }

    /**
     * 获取学生排名信息
     * 计算当前登录学生在所有学生中的排名情况
     *
     * @param request HTTP请求对象，用于获取当前登录用户
     * @return 排名信息，包含：
     *         - totalStudents: 学生总数
     *         - currentRank: 当前排名
     *         - averageScore: 平均分
     * @throws BusinessException 当用户未登录时抛出异常
     */
    @Override
    public Map<String, Object> getStudentRanking(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        
        Map<String, Object> ranking = new HashMap<>();
        
        // 获取所有学生的平均分
        List<Map<String, Object>> studentScores = studentMapper.getAllStudentAverageScores();
        
        // 计算当前学生的排名
        int currentRank = 1;
        double currentStudentScore = 0;
        
        for (Map<String, Object> score : studentScores) {
            Long studentId = (Long) score.get("studentId");
            Double avgScore = (Double) score.get("averageScore");
            
            if (studentId.equals(loginUser.getId())) {
                currentStudentScore = avgScore;
                break;
            }
            currentRank++;
        }
        
        ranking.put("totalStudents", studentScores.size());
        ranking.put("currentRank", currentRank);
        ranking.put("averageScore", currentStudentScore);
        
        return ranking;
    }

    /**
     * 分页查询学生列表
     * 实现条件组合查询和分页
     *
     * @param current 当前页码
     * @param pageSize 每页大小
     * @param studentNumber 学号关键字
     * @param name 姓名关键字
     * @param className 班级关键字
     * @param major 专业关键字
     * @param gender 性别
     * @return 分页查询结果
     */
    @Override
    public Page<Student> listStudents(Integer current, Integer pageSize, 
            String studentNumber, String name, String className, 
            String major, Integer gender) {
        // 创建查询条件
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isDelete", 0);
        
        // 添加查询条件
        if (StringUtils.isNotBlank(studentNumber)) {
            queryWrapper.like("studentNumber", studentNumber);
        }
        if (StringUtils.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }
        if (StringUtils.isNotBlank(className)) {
            queryWrapper.like("className", className);
        }
        if (StringUtils.isNotBlank(major)) {
            queryWrapper.like("major", major);
        }
        // 添加性别查询条件
        if (gender != null) {
            queryWrapper.eq("gender", gender);
        }
        
        // 按创建时间降序排序
        queryWrapper.orderByDesc("createTime");
        
        // 分页查询
        Page<Student> page = new Page<>(current, pageSize);
        return studentMapper.selectPage(page, queryWrapper);
    }

    /**
     * 获取班级统计信息
     * 调用Mapper层方法获取班级学生数量统计
     *
     * @return 班级统计结果
     */
    @Override
    public List<Map<String, Object>> getClassStatistics() {
        return studentMapper.getClassStatistics();
    }

    /**
     * 获取专业统计信息
     * 调用Mapper层方法获取专业学生数量统计
     *
     * @return 专业统计结果
     */
    @Override
    public List<Map<String, Object>> getMajorStatistics() {
        return studentMapper.getMajorStatistics();
    }

    /**
     * 获取登陆人学生信息
     * @param request
     * @return
     */
    @Override
    public UserStudentInfoVO getStudentInfo(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        Long studentId = loginUser.getStudentId();

        if(ObjectUtil.isNull(studentId)){
            throw new BusinessException(ErrorCode.ACCOUNT_DOES_NOT_EXIST);
        }
        Student student = getById(studentId);

        UserStudentInfoVO infoVO = new UserStudentInfoVO();
        infoVO.setUserId(loginUser.getId());
        infoVO.setStudentId(student.getId());
        infoVO.setName(student.getName());
        infoVO.setMajor(student.getMajor());
        infoVO.setGender(student.getGender());
        infoVO.setEmail(loginUser.getEmail());
        infoVO.setStudentNumber(student.getStudentNumber());
        infoVO.setUserProfile(loginUser.getUserProfile());

        return infoVO;
    }

    /**
     * 获取班级成绩分析
     * 分析指定班级的成绩情况，包括平均分、最高分、最低分和成绩分布
     *
     * @param className 班级名称
     * @return 成绩分析结果，包含以下信息：
     *         - studentCount: 学生总数
     *         - averageScore: 平均分
     *         - maxScore: 最高分
     *         - minScore: 最低分
     *         - totalScores: 总成绩数
     *         - distribution: 成绩分布（优秀、良好、中等、及格、不及格的人数）
     */
    public Map<String, Object> getClassScoreAnalysis(String className) {
        return null;
//        Map<String, Object> analysis = new HashMap<>();
//
//        // 获取班级所有学生
//        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("className", className);
//        List<Student> students = this.list(queryWrapper);
//
//        // 获取所有学生的成绩
//        List<Score> allScores = new ArrayList<>();
//        for (Student student : students) {
//            List<Score> scores = scoreService.getStudentScores(student.getId(), null);
//            allScores.addAll(scores);
//        }
//
//        // 计算统计信息
//        DoubleSummaryStatistics stats = allScores.stream()
//                .mapToDouble(Score::getScore)
//                .summaryStatistics();
//
//        analysis.put("studentCount", students.size());
//        analysis.put("averageScore", stats.getAverage());
//        analysis.put("maxScore", stats.getMax());
//        analysis.put("minScore", stats.getMin());
//        analysis.put("totalScores", stats.getCount());
//
//        // 计算成绩分布
//        Map<String, Long> distribution = allScores.stream()
//                .collect(Collectors.groupingBy(score -> {
//                    double s = score.getScore();
//                    if (s >= 90) return "优秀";
//                    else if (s >= 80) return "良好";
//                    else if (s >= 70) return "中等";
//                    else if (s >= 60) return "及格";
//                    else return "不及格";
//                }, Collectors.counting()));
//
//        analysis.put("distribution", distribution);
//
//        return analysis;
    }

    /**
     * 校验性别值是否有效
     */
    private boolean isValidGender(Integer gender) {
        return gender != null && (gender == 0 || gender == 1);
    }
} 